package com.seal.commons.quartz.xxljob;

import com.seal.commons.quartz.QuartzJobHandler;
import com.seal.commons.quartz.annotation.QuartzJob;
import com.xxl.job.core.executor.XxlJobExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.AnnotationUtils;

import java.util.Iterator;
import java.util.Map;

/**
 * 功能描述: <br/>
 *
 * @author yong.huang
 * @date: 2020-10-30 10:38<br/>
 * @since JDK 1.8
 */
public class XxlJobQuartzJobHandlerAutoExporter implements InitializingBean, ApplicationContextAware {

    public static final Logger LOGGER = LoggerFactory.getLogger(XxlJobQuartzJobHandlerAutoExporter.class);

    private ApplicationContext applicationContext;

    @Override
    public void afterPropertiesSet() throws Exception {
        initJob();
    }

    private void initJob() throws Exception {
        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
        Map<String, Object> beans = applicationContext.getBeansWithAnnotation(QuartzJob.class);
        Iterator<Map.Entry<String, Object>> it = beans.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, Object> entry = it.next();
            String beanName = entry.getKey();
            if (!(entry.getValue() instanceof QuartzJobHandler)) {
                throw new Exception("bean:[" + beanName + "] not extends QuartzJobHandler class");
            }
            QuartzJobHandler handler = ((QuartzJobHandler) entry.getValue());
            QuartzJob quartzJob = AnnotationUtils.findAnnotation(handler.getClass(), QuartzJob.class);
            String jobName = beanFactory.resolveEmbeddedValue(quartzJob.name());
            jobName = jobName==null || jobName.length() ==0 ? beanName : jobName;
            if(XxlJobExecutor.loadJobHandler(jobName) != null){
                throw new Exception("jobName:[" + beanName + "] exists");
            }
            LOGGER.info("xxl-job registJobHandler, name:[{}]");
            XxlJobExecutor.registJobHandler(jobName, new XxlJobQuartzJobHandlerAdapter(jobName, handler));
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}